#pragma once

#include "typedef.h"

SYS_BEGIN()

namespace detail
{

template<typename Target,typename Source>
struct a2b_{};

//string conv
template<>
struct a2b_<std::string,const char*>
{
	static std::string conv(const char *s)
	{
		return std::string(s); 
	}
};

template<>
struct a2b_<std::string,char*>
{
	static std::string conv(char *s)
	{
		return std::string(s); 
	}
};

template<>
struct a2b_<std::string,std::string>
{
	static std::string conv(std::string s)
	{
		return s; 
	}
};

#ifndef FLAG_DONTSUPPORT_WCHAR

template<>
struct a2b_<std::string,const wchar_t*>
{
	static std::string conv(const wchar_t* ws)
	{
		std::string sBuffer;
		ulong len = static_cast<ulong>(wcslen(ws));
		sBuffer.resize(len*2+8);
		sBuffer.resize(WideCharToMultiByte(CP_ACP,0,ws,len,const_cast<char*>(sBuffer.data()),static_cast<int32>(sBuffer.size()),NULL,NULL));
		return sBuffer;
	}
};

template<>
struct a2b_<std::string,wchar_t*>
{
	static std::string conv(wchar_t* ws)
	{
		return a2b_<std::string,const wchar_t*>::conv(ws);
	}
};

#endif

//number conv
template<>
struct a2b_<std::string,int32>
{
	static std::string conv(int32 n)
	{
		std::string buf(16,' ');
		buf.resize(sprintf_s(&buf.at(0),16,"%d", n)); 
		return buf;
	}
};

template<>
struct a2b_<std::string,unsigned>
{
	static std::string conv(unsigned u)
	{
		std::string buf(16,' ');
		buf.resize(sprintf_s(&buf.at(0),16,"%u", u)); 
		return buf;
	}
};

template<>
struct a2b_<std::string,long>
{
	static std::string conv(long l)
	{ 
		std::string buf(16,' ');
		buf.resize(sprintf_s(&buf.at(0),16,"%ld", l)); 
		return buf;
	}
};

template<>
struct a2b_<std::string,unsigned long>
{
	static std::string conv(unsigned long ul)
	{ 
		std::string buf(16,' ');
		buf.resize(sprintf_s(&buf.at(0),16, "%lu", ul)); 
		return buf;
	}
};

template<>
struct a2b_<std::string,real4>
{
	static std::string conv(real4 f)
	{ 
		std::string buf(16,' ');
		buf.resize(sprintf_s(&buf.at(0),16, "%lf",static_cast<real8>(f))); 
		return buf;
	}
};

template<>
struct a2b_<std::string,real8>
{
	static std::string conv(real8 d)
	{ 
		std::string buf(16,' ');
		buf.resize(sprintf_s(&buf.at(0),16, "%lf", d)); 
		return buf;
	}
};

#ifndef FLAG_DONTSUPPORT_WCHAR

template<>
struct a2b_<std::wstring,const wchar_t*>
{
	//string conv
	static std::wstring conv(const wchar_t* ws)
	{
		return std::wstring(ws); 
	}
};

template<>
struct a2b_<std::wstring,wchar_t*>
{
	//string conv
	static std::wstring conv(wchar_t* ws)
	{
		return std::wstring(ws); 
	}
};

template<>
struct a2b_<std::wstring,std::wstring>
{
	static std::wstring conv(std::wstring ws)
	{
		return ws; 
	}
};

template<>
struct a2b_<std::wstring,const char*>
{
	static std::wstring conv(const char* s)
	{

		std::wstring wsBuffer;
		ulong len = static_cast<ulong>(strlen(s));
		wsBuffer.resize(len+1);
		wsBuffer.resize(MultiByteToWideChar(CP_ACP,0,s,len,const_cast<wchar_t*>(wsBuffer.data()),static_cast<int32>(wsBuffer.size())));
		return wsBuffer;
	}
};

template<>
struct a2b_<std::wstring,char*>
{
	static std::wstring conv(char* s)
	{
		return a2b_<std::wstring,const char*>::conv(s);
	}
};


//number conv
template<>
struct a2b_<std::wstring,int32>
{
	static std::wstring conv(int32 n)
	{
		std::wstring buf(16,L' ');
		buf.resize(swprintf_s(&buf.at(0),16,L"%d", n)); 
		return buf;
	}
};

template<>
struct a2b_<std::wstring,unsigned>
{
	static std::wstring conv(unsigned u)
	{
		std::wstring buf(16,L' ');
		buf.resize(swprintf_s(&buf.at(0),16,L"%u", u)); 
		return buf;
	}
};

template<>
struct a2b_<std::wstring,long>
{
	static std::wstring conv(long l)
	{ 
		std::wstring buf(16,L' ');
		buf.resize(swprintf_s(&buf.at(0),16,L"%ld", l)); 
		return buf;
	}
};

template<>
struct a2b_<std::wstring,unsigned long>
{
	static std::wstring conv(unsigned long ul)
	{ 
		std::wstring buf(16,L' ');
		buf.resize(swprintf_s(&buf.at(0),16, L"%lu", ul)); 
		return buf;
	}
};

template<>
struct a2b_<std::wstring,real4>
{
	static std::wstring conv(real4 f)
	{ 
		std::wstring buf(16,L' ');
		buf.resize(swprintf_s(&buf.at(0),16, L"%lf",static_cast<real8>(f))); 
		return buf;
	}
};

template<>
struct a2b_<std::wstring,real8>
{
	static std::wstring conv(real8 d)
	{ 
		std::wstring buf(16,L' ');
		buf.resize(swprintf_s(&buf.at(0),16, L"%lf", d)); 
		return buf;
	}
};

#endif

}

template<typename Target>
struct a2b
{
	template<typename Source>
	static Target conv(Source s)
	{
		return detail::a2b_<Target,Source>::conv(s);
	}
};

SYS_END()